#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2021/7/21 13:49
# @Author  : Samge
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import hashlib
import os
import random
from functools import lru_cache
from urllib.parse import parse_qsl

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


def save_txt_file(_txt, _path, _type='w+'):
    """保存文件"""
    try:
        with open(_path, _type, encoding='utf-8') as f:
            f.write(_txt)
            f.flush()
            f.close()
    except:
        pass


def read_txt_file(_path):
    """读取文件"""
    if os.path.exists(_path) is False:
        return None
    with open(_path, "r", encoding='utf-8') as f:  # 打开文件
        data = f.read()
        f.close()
        if data == '':
            return None
        else:
            return data


def read_txt_file_random_line(_path):
    """读取文件某一行"""
    if os.path.exists(_path) is False:
        return None
    with open(_path, "r") as f:  # 打开文件
        lines = f.readlines()
        return lines[random.choice([i for i in range(len(lines))])]


def read_txt_file_line(_path, curr_line):
    """读取文件某一行"""
    if os.path.exists(_path) is False:
        return None
    with open(_path, "r") as f:  # 打开文件
        lines = f.readlines()
        if curr_line < len(lines):
            return lines[curr_line]
        else:
            return None


def read_txt_file_scope(_path, start_line=None, end_line=None):
    """读取文件某一段区间内容"""
    try:
        if os.path.exists(_path) is False:
            return None
        with open(_path, "r") as f:  # 打开文件
            lines = f.readlines()
            if start_line is None:
                start_line = 0
            if end_line is None:
                end_line = len(lines)
            return lines[start_line: end_line]
    except Exception as e:
        print(e)
        return None


def save_txt_file_scope(_path, start_line=None, end_line=None):
    """仅保存某一段区间内容"""
    try:
        if os.path.exists(_path) is False:
            return None
        _txt = ''
        with open(_path, "r") as f:  # 打开文件
            lines = f.readlines()
            if start_line >= len(lines):
                _txt = ''
            else:
                if start_line is None:
                    start_line = 0
                if end_line is None:
                    end_line = len(lines)
                _txt = ''.join(lines[start_line: end_line])
        # print(_txt)
        with open(_path, "w") as f:  # 打开文件
            f.write(_txt)
            f.flush()
            f.close()
    except Exception as e:
        print(e)


def read_txt_file_lines(_path):
    """读取文件行数"""
    # 文件比较小
    return len(open(_path, 'rU').readlines())


def get_ocname_keys(_path=None):
    """读取公司关键词"""
    if _path is None:
        _path = '../ocname_keys.txt'
    result = read_txt_file(_path) or ''
    return result.split('\n')


def get_file_ext(file_name):
    """通过split方式获取文件扩展名"""
    if file_name and '.' in file_name:
        _split = file_name.split('.')
        return _split[len(_split) - 1]
    return None


def get_file_name_from_disposition(content_disposition):
    """
    从响应头的Content-Disposition中读取文件名

    例如：
    'form-data; name=file;filename=test.txt;'
    'attachment;filename=xxx.doc'
    """
    if content_disposition is None:
        return None
    if type(content_disposition) is bytes:
        content_disposition = str(content_disposition, encoding="utf-8")
    if type(content_disposition) is not str:
        raise ValueError('传入的参数需要字符串类型')
    _d = dict(parse_qsl(content_disposition))
    return _d.get('filename')


def check_and_clen_file(file_path, max_size=None, clean_percent=None):
    """
    检测文件大小，如果超过，则按比例清理该文件文件
    ：file_path: 文件路径
    :max_size: 限制的大小，单位（M）,默认10M
    :clean_percent: 清除的百分比（从第一行开始数），取值范围（0~1] ，默认清空所有内容
    """
    if os.path.exists(file_path) is False:
        return
    if file_path is None:
        raise ValueError('文件路径不能为空')
    if clean_percent == 0 or clean_percent > 1:
        raise ValueError('clean_percent的取值范围应该为(0, 1]')
    if max_size is None:
        max_size = 10
    if clean_percent is None:
        clean_percent = 1
    _size = os.path.getsize(file_path) / 1024 / 1024
    print('文件：{} 当前：{}M  限制：{}M'.format(file_path, _size, max_size))
    if _size > max_size:
        print('文件（{}）大小超过{}M，清空该文件前{}%的内容'.format(file_path, max_size, clean_percent * 100))
        save_txt_file_scope(file_path, start_line=int(read_txt_file_lines(file_path) * clean_percent))


def get_file_md5(file_path):
    """
    计算文件的md5
    :file_path:
    """
    m = hashlib.md5()   # 创建md5对象
    with open(file_path, 'rb') as fobj:
        while True:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)  # 更新md5对象
    return m.hexdigest()    # 返回md5对象


@lru_cache()
def get_local_html_path():
    """获取本地的html文件绝对路径，少部分scrapy项目需要使用"""
    _path = get_local_child_path('/temp_files/scrapy_temp_pager.html')
    if os.path.exists(_path) is False:
        os.makedirs(get_local_child_path('/temp_files'))
        temp_html_txt = '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><p>这是本地的一个html，部门scrapy爬虫需要用到</p></head><body></body></html>'
        save_txt_file(temp_html_txt, _path)
    _path = 'file:{}'.format(_path)
    print(_path)
    return _path


def get_local_child_path(child_path):
    """获取本项目下某子文件/子目录 的绝对路径"""
    return '{}{}'.format(get_project_path(), child_path)


def get_project_path():
    """获取当前项目路径下的绝对路径"""
    return os.path.abspath('.')


def get_parent_path(file_path, sep='.'):
    """
    获取文件的父路径
    :param file_path: 当前文件路径
    :param sep: 级数
        .代表当前文件父级路径,
        ..代表父级的父级路径
    :return:
    """
    return os.path.abspath(os.path.dirname(file_path)+os.path.sep+sep)
